﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Backend.JYD.Model.Bid;
using Backend.JYD.Model;
using Backend.JYD.Model.Cust;

namespace Backend.JYD.BLL.Bid
{
    public class PayPlanBLL
    {
        private static readonly IDAL.Bid.IPayPlan idal = Factory.DALFactory.CreateEFDAL<IDAL.Bid.IPayPlan>("DAL.PayPlanDAL");
        
        public const int WARNING_DAY = 5; //提前5天检查逾期风险
        public const int REPAY_DAY = 30; //逾期30天应按规则垫付

        public enum enumRepayType { 持续垫资 = 0, 逾期了结 = 1 }
        public enum enumPlanType { 等额本息 = 0 }
        public enum enumPlanStatus { 未到期 = 0, 已完成 = 1, 逾期未付 = 2, 已垫付 = 3 }

        //等额本息情况下，每月还款总额
        public static decimal MonthlyAverageCapital(decimal loanMoney, decimal monthRate, int term)
        {
            //?double
            decimal pow = (decimal)Math.Pow((double)(1 + monthRate), term);
            return loanMoney * monthRate * pow / (pow - 1);
        }

        public static decimal TermInterest(decimal totalMoney, decimal yearRate, int term)
        {
            return totalMoney * (yearRate / 100) * (term / 12);
        }

        public Int64 AddPayPlan(PayPlan plan)
        {
            if (plan.InviteId <= 0) return 0;

            return idal.AddPayPlan(plan);
        }

        public bool UpdatePayPlan(PayPlan plan)
        {
            if (plan.InviteId <= 0) return false;

            return idal.UpdatePayPlan(plan);
        }

        public bool CreatePayPlan(InviteInfo info, decimal monthlyAmount)
        {
            int i = 0;
            for (; i < info.Term; i++)
            {
                PayPlan plan = new PayPlan();
                plan.InviteId = info.InviteId;
                plan.Status = (int)enumPlanStatus.未到期;
                plan.PayDate = ((DateTime)info.BidStartDate).AddMonths(i + 1);
                plan.PayAmount = monthlyAmount;
                plan.TermNum = i + 1;
                if (i == info.Term - 1) 
                    plan.IsLastPlan = true; 
                else 
                    plan.IsLastPlan = false;

                AddPayPlan(plan);
            }
            return i > 0;
        }

        //执行today的所有还款计划
        public long RunPayPlan(DateTime today)
        {
            if (today == null) today = DateTime.Today;
            IList<PayPlan> lstPlan = idal.GetRunPlan(today);

            if (lstPlan == null || lstPlan.Count == 0) return 0;
            InviteInfoBLL inviteBll = new InviteInfoBLL();

            long failNum = 0;
            foreach (PayPlan plan in lstPlan)
            {
                //执行还款
                bool planRet = inviteBll.PayInvite(plan);

                if (!planRet)  //出现逾期，先不考虑部分逾期的情况
                {
                    failNum++;
                    plan.LessMoney = true; //如果是余额不足的原因
                    plan.Status = (int)enumPlanStatus.逾期未付;
                }
                else //如果该plan的转账全部成功
                {
                    plan.LessMoney = false;
                    plan.Status = (int)enumPlanStatus.已完成;
                    plan.IsValid = false;
                }
                idal.UpdatePayPlan(plan);
            }
            return failNum;
        }

        //对所有逾期30天的还款计划，执行垫资结单操作
        public long RepayPlan(enumRepayType repayType)
        {
            IList<PayPlan> lstRepayPlan = idal.GetRepayPlan(REPAY_DAY);
            if (lstRepayPlan == null || lstRepayPlan.Count == 0) return 0;

            InviteInfoBLL inviteBll = new InviteInfoBLL();
            BidRecordBLL bidBll = new BidRecordBLL();
            long repayNum = 0;
            foreach (PayPlan repay in lstRepayPlan)
            {
                repayNum++;

                //融资项目终止
                inviteBll.RepayInvite(repay.InviteId, repay.TermNum.Value, repayType);

                //通过第三方接口执行第三方垫资...

                if (repayType == enumRepayType.逾期了结)
                {
                    //剩余账期置无效
                    IList<PayPlan> lstPlan = idal.GetPayPlanByInviteId(repay.InviteId);
                    if (lstPlan != null)
                    {
                        foreach (PayPlan pay in lstPlan)
                        {
                            if (pay.PayDate >= repay.PayDate)
                            {
                                pay.IsValid = false;
                                pay.Status = (int)enumPlanStatus.已垫付;
                                idal.UpdatePayPlan(pay);
                            }
                        }
                    }
                }
                //更新投标记录
                bidBll.RepayBid(repay.InviteId, repay.TermNum.Value, repayType);
            }
            return repayNum;
        }

        //检查账户还款逾期风险
        public long CheckWarningPlan(DateTime start)
        {
            if (start == null) start = DateTime.Today;
            IList<PayPlan> lstPlan = idal.CheckWarningPayPlan(start, WARNING_DAY);

            if (lstPlan == null || lstPlan.Count == 0) return 0;
            long lessMoneyNum = 0;
            foreach (PayPlan plan in lstPlan)
            {
                plan.WarningDay = plan.PayDate.Value.Date.CompareTo(start); //风险天数
                bool lessMoney = true;

                //通过invite、userAccount和第三方接口，检查账户余额是否充足...
                
                if (lessMoney)
                {
                    lessMoneyNum++;
                    plan.LessMoney = true;

                    idal.UpdatePayPlan(plan);
                }
            }
            return lessMoneyNum;
        }
    }
}
